import 'dart:io';

import 'package:common_utils/common_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_getx_project/constant/main_api_constant.dart';
import 'package:flutter_getx_project/entity/version_entity.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:path_provider/path_provider.dart';
import 'package:percent_indicator/linear_percent_indicator.dart';
import 'package:x_core/x_core.dart';
import 'package:x_project/x_project.dart';

/// Created by XieXin on 2021/8/3.
/// 升级工具类
class UpgradeUtils {
  static const String appApkName = "app.apk";

  /// 检查版本是否需要更新，有更新会显示版本更新信息对话框，包含下载和安装功能
  /// [showLoading] 显示加载进度
  /// [hideLoading] 隐藏加载进度
  /// [isShowToast] 是否显示Toast
  static void checkVersion(
    BuildContext context, {
    required VoidCallback showLoading,
    required VoidCallback hideLoading,
    Function(bool isUpgrade)? onUpgrade,
    bool isShowToast = false,
  }) async {
    bool isConnected = await NetUtils.isConnected();
    if (!isConnected) {
      NotNetError error = NotNetError();
      if (isShowToast) ToastUtils.showLong(error.message);
      if (onUpgrade != null) onUpgrade(false);
      LogUtil.v(error.message);
      return;
    }

    if (isShowToast) showLoading();
    Map<String, dynamic> map = {};
    map["platform"] = Platform.isAndroid ? "1" : "0"; //平台类型 0-ios 1-安卓
    VersionEntity? entity = await DioHolder().get<VersionEntity>(
      MainApiConstant.getVersion,
      queryParameters: map,
      onError: (NetException e) {
        if (onUpgrade != null) onUpgrade(false);
        if (isShowToast) ToastUtils.showLong(e.message);
        if (isShowToast) hideLoading();
        return true;
      },
    );

    if (isShowToast) hideLoading();
    try {
      if (entity?.code == BaseEntity.okCode && entity?.data != null) {
        if (isShowToast) hideLoading();
        PackageInfo.fromPlatform().then((PackageInfo packageInfo) {
          if (entity!.data!.version > int.parse(packageInfo.buildNumber)) {
            //有版本更新
            showUpgradeDialog(context, entity.data!);
          } else {
            deleteApk();
            if (isShowToast) ToastUtils.showLong("暂无新版本");
          }
        });
      } else {
        if (isShowToast) ToastUtils.showLong(DataError().message);
        if (isShowToast) hideLoading();
        if (onUpgrade != null) onUpgrade(false);
      }
    } catch (e) {
      if (onUpgrade != null) onUpgrade(false);
      JsonParseError error = JsonParseError();
      LogUtil.e("${error.message} : $e");
      if (isShowToast) ToastUtils.showLong(error.message);
      if (isShowToast) hideLoading();
    }
  }

  static void deleteApk() async {
    var directory = await getTemporaryDirectory();
    String savePath = "${directory.path}/${UpgradeUtils.appApkName}";

    File file = File(savePath);
    file.exists().then((value) {
      if (value) file.deleteSync();
    });
  }

  static void showUpgradeDialog(context, VersionData version) {
    showDialog<void>(
      context: context,
      barrierDismissible: false,
      builder: (context) {
        return Material(
          type: MaterialType.transparency, //透明类型
          child: WillPopScope(
              //禁用返回键
              child: Center(
                child: Container(
                  margin: EdgeInsets.all(50.w),
                  width: double.infinity,
                  height: 350.h,
                  decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(20.w),
                  ),
                  child: UpgradeWidget(version: version),
                ),
              ),
              onWillPop: () async {
                return Future.value(false);
              }),
        );
      },
    );
  }

  static const MethodChannel _methodChannel =
      MethodChannel("com.pensoon.app.install");

  static void installApk(filePath) async {
    try {
      Map<String, dynamic> data = {};
      data["path"] = filePath;

      await _methodChannel.invokeMethod("install", data);
    } on PlatformException catch (e) {
      ToastUtils.showLong("安装失败");
      LogUtil.v(e.toString());
    }
  }
}

class UpgradeWidget extends StatefulWidget {
  final VersionData version;

  const UpgradeWidget({required this.version, Key? key}) : super(key: key);

  @override
  UpgradeWidgetState createState() => UpgradeWidgetState();
}

class UpgradeWidgetState extends State<UpgradeWidget> {
  late String _savePath;

  ///是否显示版本提示
  bool _isShowVersionHint = true;

  DownloadState _state = DownloadState.none;
  int _count = 0;
  int _total = 0;
  String? _hint;

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.transparent,
      child: Column(
        children: [
          SizedBox(
            width: double.infinity,
            height: 80.w,
            child: Stack(
              alignment: Alignment.center,
              children: [
                Text(
                  "有新版本 ${widget.version.versionName ?? 'V1.0.0'}",
                  style: TextStyle(
                    fontSize: 36.w,
                    color: XColors.textColor33,
                    fontWeight: FontWeight.w500,
                  ),
                ),
                widget.version.isForce
                    ? const SizedBox.shrink()
                    : Positioned(
                        right: 12.w,
                        child: GestureDetector(
                          onTap: () => Navigator.of(context).pop(),
                          child: Container(
                            width: 80.w,
                            height: 80.w,
                            padding: EdgeInsets.symmetric(vertical: 20.w),
                            child: Icon(
                              const IconData(0xe889, fontFamily: "Icons"),
                              size: 42.w,
                              color: XColors.textColorB1,
                            ),
                          ),
                        ),
                      ),
              ],
            ),
          ),
          Expanded(
            child: Padding(
              padding: EdgeInsets.only(bottom: 32.w),
              child: !_isShowVersionHint
                  ? Center(
                      child: Container(
                        margin: EdgeInsets.symmetric(horizontal: 32.w),
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            _upgradeIndicatorWidget(context),
                            Padding(
                              padding: EdgeInsets.only(top: 20.w),
                              child: Text(_hint ?? ""),
                            ),
                          ],
                        ),
                      ),
                    )
                  : XScrollView(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      padding: EdgeInsets.symmetric(horizontal: 32.w),
                      children: [
                        SizedBox(
                          width: double.infinity,
                          child: Text(
                            widget.version.content ?? '有新版本',
                          ),
                        ),
                      ],
                    ),
            ),
          ),
          _button(),
        ],
      ),
    );
  }

  ///升级指示器部件
  Widget _upgradeIndicatorWidget(context) {
    double percent = _total == 0 ? 0 : (_count / _total);
    return LayoutBuilder(
      builder: (context, constrains) {
        return LinearPercentIndicator(
          width: constrains.maxWidth,
          lineHeight: 40.w,
          percent: percent,
          center: Text(
            "${NumUtil.getNumByValueDouble(percent * 100, 2)}%",
            style: TextStyle(fontSize: 28.w, color: Colors.white),
          ),
          barRadius: Radius.circular(20.w),
          progressColor: Get.theme.primaryColor,
        );
      },
    );
  }

  Widget _button() {
    isExists().then((value) {
      if (value && _state == DownloadState.none) {
        setState(() {
          _state = DownloadState.complete;
        });
      }
    });
    switch (_state) {
      case DownloadState.complete:
        return XButton(
          text: "立即安装",
          onPressed: () {
            UpgradeUtils.installApk(_savePath);
          },
          height: 76.w,
          margin: EdgeInsets.only(left: 32.w, bottom: 32.w, right: 32.w),
        );
      case DownloadState.fail:
        return XButton(
          text: "重试",
          onPressed: () {
            setState(() {
              if (widget.version.url == null) {
                _hint = "下载App链接不存在";
              } else {
                _isShowVersionHint = false;
                _state = DownloadState.downloading;
                download(widget.version.url!);
              }
            });
          },
          height: 76.w,
          margin: EdgeInsets.only(left: 32.w, bottom: 32.w, right: 32.w),
        );
      case DownloadState.downloading:
        return XButton(
          text: "下载中...",
          height: 76.w,
          margin: EdgeInsets.only(left: 32.w, bottom: 32.w, right: 32.w),
        );
      default:
        return XButton(
          text: "立即升级",
          onPressed: () {
            setState(() {
              if (widget.version.url == null) {
                _hint = "下载App链接不存在";
                _isShowVersionHint = false;
                _state = DownloadState.fail;
              } else {
                _isShowVersionHint = false;
                _state = DownloadState.downloading;
                download(widget.version.url!);
              }
            });
          },
          height: 76.w,
          margin: EdgeInsets.only(left: 32.w, bottom: 32.w, right: 32.w),
        );
    }
  }

  Future<bool> isExists() async {
    var directory = await getTemporaryDirectory();
    _savePath = "${directory.path}/${UpgradeUtils.appApkName}";

    File file = File(_savePath);
    file.exists().then((value) => LogUtil.v("=====> app.apk 是否存在 ：$value"));
    return file.exists();
  }

  void download(String url) async {
    var directory = await getTemporaryDirectory();
    NetUtils.isConnected().then((isConnected) {
      if (!isConnected) {
        setState(() {
          _hint = "无网络";
          _state = DownloadState.fail;
        });
        return;
      }
      _savePath = "${directory.path}/${UpgradeUtils.appApkName}";
      LogUtil.v("=====> 版本更新保存位置：$_savePath");
      DioHolder().download(
        url,
        _savePath,
        onReceiveProgress: (int count, int total) {
          setState(() {
            _count = count;
            _total = total;
          });
        },
        onSuccess: () {
          setState(() {
            _state = DownloadState.complete;
            UpgradeUtils.installApk(_savePath);
          });
        },
        onError: (NetException e) {
          setState(() {
            _hint = e.message;
            _state = DownloadState.fail;
          });
        },
      );
    });
  }
}

enum DownloadState {
  ///下载中
  downloading,

  ///下载完成
  complete,

  ///下载失败
  fail,

  ///无
  none,
}
